package whu.cachhe.makeorder.view;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.util.LinkedList;

import whu.cachhe.makeorder.R;


/**
 *
 * Created by CocoAdapter on 2018/2/25.
 */
public class GalleryView extends ViewPager {
    protected static final int MAX_CACHE_NUM = 5;
    protected static final int NUM_OF_VIEWS = 3;
    protected LinkedList<View> viewCache; // ListView 依然有OOM的危险

    private Context context;
    private PagerAdapter photoAdapter;
    private int numOfViews;
    private boolean isEmpty = true;

    private OnBindEachViewData onBindEachViewData;
    private OnItemClickListener onItemClickListener;

    public GalleryView(Context context) {
        super(context);
        init(context);
    }

    public GalleryView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        this.context = context;
        viewCache = new LinkedList<>();
        numOfViews = NUM_OF_VIEWS;
    }

    public void performItemClick(int position){
        if (onItemClickListener != null)
            onItemClickListener.onItemClick(getChildAt(position), position);
    }

    public interface OnItemClickListener{
        /**
         *
         * @param view the value of {@link OnBindEachViewData#getView()}
         * @param position the position in all items
         */
        void onItemClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    public void bindData(OnBindEachViewData onBindEachViewData){
        this.onBindEachViewData = onBindEachViewData;
        setPhotoAdapter();

        if (this.onBindEachViewData != null) {
            setOffscreenPageLimit(this.onBindEachViewData.getCount());
            setClipChildren(false); // more views in one screen, if the size of each is too small
            setPageMargin(getResources().getDimensionPixelSize(R.dimen.gallery_view_page_margin));
        }
    }

    /**
     * the bridge between each item and data
     */
    public interface OnBindEachViewData {
        /**
         *
         * @return item view
         */
        View getView();

        /**
         * do the view-viewHolder mapping in this method
         * @param view the value of {@link #getView()}
         * @return viewHolder
         */
        Object getViewHolder(View view);

        /**
         *
         * @return the total number of data
         */
        int getCount();

        /**
         *
         * @param  position the current position in all data, also the views
         * @param viewHolder the viewHolder in the view, defined in {@link #getViewHolder(View view)}. When use this method, do a type conversion
         */

        void bindDataToEachView(Object viewHolder, int position);
    }

    /**
     * 最终放置多少个会比较{@link OnBindEachViewData#getCount()}的结果，取最小值。
     * @param num 同屏放置多少个item
     */
    public void setNumOfItemViews(int num){
        numOfViews = num;
        if (onBindEachViewData != null){
            setPhotoAdapter();
        }
    }

    public boolean isEmpty() {
        return isEmpty;
    }

    private void setPhotoAdapter() {
         photoAdapter = new PagerAdapter() {
            @Override
            public int getCount() {
                if (onBindEachViewData == null)
                    return 0;

                int count = onBindEachViewData.getCount();
                isEmpty = count == 0;

                return  count;
            }

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }

            @Override
            public Object instantiateItem(ViewGroup container, final int position) {
                View convertView = null;
                Object holder = null;

                if (viewCache.size() == 0){
                    if (onBindEachViewData != null){
                        convertView = onBindEachViewData.getView();
                        holder = onBindEachViewData.getViewHolder(convertView);
                        convertView.setTag(holder);
                    }
                } else {
                    convertView = viewCache.removeFirst();
                    holder = convertView.getTag();
                }

                if (onBindEachViewData != null){
                    onBindEachViewData.bindDataToEachView(holder, position);
                    convertView.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (onItemClickListener != null)
                                onItemClickListener.onItemClick(v, position);
                        }
                    });
                }

                container.addView(convertView);
                return convertView;
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object){
                container.removeView((View) object);

                if (viewCache.size() >= MAX_CACHE_NUM) // delete the oldest cached view
                    viewCache.removeFirst();

                viewCache.addLast((View) object);
            }

            @Override
            public float getPageWidth(int position) {
                if (onBindEachViewData != null){
                    int count = onBindEachViewData.getCount();
                    if (count < numOfViews){
                        return 1f / count;
                    }
                }
                return 1f / numOfViews;
            }


        };

        setAdapter(photoAdapter);
    }

}
